import 'package:built_collection/built_collection.dart';
import 'package:equatable/equatable.dart';
import 'package:backend.core/core/domain/entities/api/web/api_web_purchased_subscription.dart';
import 'package:backend.purchases/infrastructure/dtos/api/api_time_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/web/api_web_purchased_item_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/web/api_web_purchased_subscription_status_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/web/api_web_purchased_subscription_transaction_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/api/web/api_web_purchased_subscription_transaction_dto_factory.dart';

const kApiWebPurchasedSubscriptionTransactionsKey = 'transactions';
const kApiWebPurchasedSubscriptionAutoRenewalEnabledKey = 'auto_renewal_enabled';
const kApiWebPurchasedSubscriptionOriginalTransactionIdKey = 'original_transaction_id';
const kApiWebPurchasedSubscriptionStatusKey = 'status';
const kApiWebPurchasedSubscriptionExpirationTimeKey = 'expiration_time';

const kApiWebPurchasedSubscriptionTypeValue = 'purchased_subscription';

class ApiWebPurchasedSubscriptionDto extends Equatable implements ApiWebPurchasedItemDto {
  const ApiWebPurchasedSubscriptionDto._internal({
    required this.purchaseItemSku,
    required this.transactionDtos,
    required this.originalTransactionId,
    required this.autoRenewalEnabled,
    required this.statusDto,
    required this.expirationTimeDto,
    required this.test,
  });

  @override
  final String purchaseItemSku;

  @override
  final bool test;

  final String originalTransactionId;
  final bool autoRenewalEnabled;
  final ApiWebPurchasedSubscriptionStatusDto statusDto;
  final ApiTimeDto? expirationTimeDto;
  final BuiltList<ApiWebPurchasedSubscriptionTransactionDto> transactionDtos;

  @override
  List<Object?> get props {
    return [
      purchaseItemSku,
      transactionDtos,
      originalTransactionId,
      autoRenewalEnabled,
      statusDto,
      expirationTimeDto,
      test,
    ];
  }

  @override
  String get type => kApiWebPurchasedSubscriptionTypeValue;

  factory ApiWebPurchasedSubscriptionDto.fromEntity(
      ApiWebPurchasedSubscription purchasedSubscription) {
    final statusDto = ApiWebPurchasedSubscriptionStatusDto.fromEntity(purchasedSubscription.status);

    final transactionDtos = purchasedSubscription.transactions.map((transaction) {
      return ApiWebPurchasedSubscriptionTransactionDtoFactory().fromEntity(transaction);
    }).toBuiltList();

    ApiTimeDto? expirationTimeDto;

    if (purchasedSubscription.expirationTime != null) {
      expirationTimeDto = ApiTimeDto.fromEntity(purchasedSubscription.expirationTime!);
    }

    return ApiWebPurchasedSubscriptionDto._internal(
      purchaseItemSku: purchasedSubscription.purchaseItemSku,
      transactionDtos: transactionDtos,
      autoRenewalEnabled: purchasedSubscription.autoRenewalEnabled,
      statusDto: statusDto,
      expirationTimeDto: expirationTimeDto,
      test: purchasedSubscription.test,
      originalTransactionId: purchasedSubscription.originalTransactionId,
    );
  }

  @override
  Map<String, dynamic> toJson() {
    final transactionJsons = transactionDtos.map((transactionDto) {
      return transactionDto.toJson();
    }).toList();

    return {
      kApiWebPurchasedItemTypeKey: type,
      kApiWebPurchasedItemPurchaseItemSkuKey: purchaseItemSku,
      kApiWebPurchasedItemTestKey: test,
      kApiWebPurchasedSubscriptionAutoRenewalEnabledKey: autoRenewalEnabled,
      kApiWebPurchasedSubscriptionStatusKey: statusDto.toString(),
      kApiWebPurchasedSubscriptionExpirationTimeKey: expirationTimeDto?.toString(),
      kApiWebPurchasedSubscriptionTransactionsKey: transactionJsons,
      kApiWebPurchasedSubscriptionOriginalTransactionIdKey: originalTransactionId,
    };
  }
}
